package br.com.virtual.base.controller.carrinho;

import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;

import br.com.virtual.base.controller.util.VirtualMB;
import br.com.virtual.cadastrar.model.Pessoa;
import br.com.virtual.cadastrar.model.Produto;
import br.com.virtual.cadastrar.model.Usuario;
import br.com.virtual.correio.enums.TipoFrete;
import br.com.virtual.correio.service.CalculadorDeFreteService;
import br.com.virtual.vender.model.Frete;
import br.com.virtual.vender.model.Interesse;
import br.com.virtual.vender.model.ItemVenda;
import br.com.virtual.vender.model.Venda;
import br.com.virtual.vender.service.InteresseService;

//import br.com.virtual.service.CarrinhoService;

@ManagedBean
@SessionScoped
public class CarrinhoMB extends VirtualMB {

	
	private static final long serialVersionUID = 1L;

	private Produto produto;
	private Venda carrinho;
	private int maxParcela = 12;
	private String nav;
	
	private Frete frete;
	private Frete freteProduto;
	private String cepDestino;
	private TipoFrete tipoFrete;
//	private Boolean exibirInputFrete;
	
	@EJB
	InteresseService intesseService;

	@EJB
	CalculadorDeFreteService calculadorDeFreteService;
	// @EJB
	// PessoaFisicaService pessoaFisicaService;
	// @EJB
	// PessoaJuridicaService pessoaJuridicaService;

	// @EJB
	// CarrinhoService carrinhoService;

	@PostConstruct
	public void init() {

		novoCarrinho();
		novoProduto();
//		defineExibirInputFrete(null);
	}
	
	public boolean isFreteCalculavel(){
		
		if( cepDestino != null && !cepDestino.isEmpty())
			return true;
		return false;
	}
	
//	public void defineExibirInputFrete(Boolean exibir){
//		
//		if( exibir != null)
//			exibirInputFrete = exibir;
//		else
//			if( cepDestino == null)
//				exibirInputFrete = true;
//			else
//				exibirInputFrete = false;
//	}
	
//	public Boolean exibirFreteCalculado(){
//		return !exibirInputFrete();
//	}
	
//	public Boolean exibirInputFrete(){
//		return exibirInputFrete;
//	}
	
	public void calculaFrete(Produto produto){
		
		if( cepDestino != null && !cepDestino.isEmpty() && tipoFrete != null){
			
			if( produto == null ){
				if( carrinho != null && carrinho.getItens().size() > 0 )
					frete = calculadorDeFreteService.calculaPrecoPrazo(carrinho.getItens(), tipoFrete, CEP_ORIGEM, cepDestino);
			}else
				freteProduto = calculadorDeFreteService.calculaPrecoPrazo(produto, tipoFrete, CEP_ORIGEM, cepDestino);
		
//			defineExibirInputFrete(false);
		}
	}
	
	
	
	private void novoCarrinho() {
		this.carrinho = new Venda();
	}

	public void novoProduto() {
		this.produto = new Produto();
	}

	public void resetCarrinho() {
		this.novoCarrinho();
		this.gravarInteresse();
	}

	private ItemVenda createItemVenda(Produto produto) {

		ItemVenda itemVenda = new ItemVenda();
		itemVenda.setProduto(produto);
		itemVenda.setVenda(carrinho);
		itemVenda.setQuantidade(1);
		itemVenda.setTotal(produto.getPreco_venda_desconto());

		return itemVenda;

	}

	private boolean addItemCarrinho(ItemVenda itemVenda) {

		if (!carrinho.getItens().contains(itemVenda)) {
			carrinho.getItens().add(itemVenda);
			sumTotalCarrinho(itemVenda.getTotal(), itemVenda.getQuantidade());
			definirMaxParcela(itemVenda.getProduto().getNumero_parcelas());

			this.gravarInteresse();
			return true;
		} else {
			return false;
		}
	}

	private void gravarInteresse() {

		if (getUsuarioLogado() != null) {
			Pessoa pessoa = getUsuarioLogado().getPessoa();
			pessoa.getInteresse().setProdutos(new TreeSet<Produto>());

			for (ItemVenda iv : this.carrinho.getItens())
				pessoa.getInteresse().getProdutos().add(iv.getProduto());

//			this.intesseService.create(pessoa.getInteresse());

		}
	}

	public void recuperarInteresse() {

		if (getUsuarioLogado() != null) {
			Pessoa pessoa = getUsuarioLogado().getPessoa();
			Interesse interesse = pessoa.getInteresse();

			for (Produto p : interesse.getProdutos()) {
				this.addProdutoCarrinho(p);
			}

			this.redirectToCarrinhoPage();
		}

	}

	public void descartarInteresse() {

		if (getUsuarioLogado() != null) {
			Pessoa pessoa = getUsuarioLogado().getPessoa();
			Interesse interesse = pessoa.getInteresse();

			this.intesseService.delete(interesse);
			pessoa.setInteresse(null);
			pessoa.getInteresse();
		}

	}

	public String addProdutoEIrCarrinho(Produto produto) {

		addProdutoCarrinho(produto);
		this.calculaFrete(null);
		return nav;
	}

	public void addProdutoCarrinho(Produto produto) {

		ItemVenda itemVenda = createItemVenda(produto);

		if (addItemCarrinho(itemVenda)) {
			nav = "/vender/carrinho?faces-redirect=true";
			addMessage("Produto adicionado ao carrinho.",
					FacesMessage.SEVERITY_INFO);
		} else {
			nav = "/vender/carrinho?faces-redirect=true";
			addMessage("Este produto já está no carrinho.",
					FacesMessage.SEVERITY_WARN);
		}
	}

	public void addItemVendaCarrinho(ItemVenda item) {

		this.addItemCarrinho(item);

	}

	private void sumTotalCarrinho(Double total, int quantidade) {

		carrinho.setTotalVenda(carrinho.getTotalVenda() + total);
		carrinho.setTotalGeral(carrinho.getTotalGeral() + total);
		
//		carrinho.setTotal(carrinho.getTotal() + total);
		carrinho.setTotalItens(carrinho.getTotalItens() + quantidade);
	}

	private void subTotalCarrinho(Double total, int quantidade) {

		carrinho.setTotalVenda(carrinho.getTotalVenda() - total);
		carrinho.setTotalGeral(carrinho.getTotalGeral() - total);
		
//		carrinho.setTotal(carrinho.getTotal() - total);
		carrinho.setTotalItens(carrinho.getTotalItens() - quantidade);
	}

	public void remover(ItemVenda itemVenda) {

		carrinho.getItens().remove(itemVenda);
		subTotalCarrinho(itemVenda.getTotal(), itemVenda.getQuantidade());

		this.gravarInteresse();
		this.calculaFrete(null);
		
		addMessage("Produto removido do carrinho.", FacesMessage.SEVERITY_INFO);
	}

	public void calculaTotalItem(ItemVenda itemVenda) {

		if (itemVenda.getQuantidade() > itemVenda.getProduto().getQuantidade()) {
			itemVenda.setQuantidade(itemVenda.getProduto().getQuantidade());
			addMessage("Não temos em estoque a quantidade digitada.",
					FacesMessage.SEVERITY_WARN);
		}

		// carrinho.setTotal(carrinho.getTotal() - itemVenda.getTotal());

		definirMaxParcela(itemVenda.getProduto().getNumero_parcelas());

		subTotalCarrinho(itemVenda.getTotal(), itemVenda.getQuantidade());
		if (itemVenda.getProduto().getPreco_venda_desconto() > 0)
			itemVenda.setTotal(itemVenda.getQuantidade()
					* (itemVenda.getProduto().getPreco_venda_desconto()));
		// carrinho.setTotal(carrinho.getTotal() + itemVenda.getTotal());
		sumTotalCarrinho(itemVenda.getTotal(), itemVenda.getQuantidade());
		
		calculaFrete(null);
	}

	private void definirMaxParcela(int valorParcela) {

		maxParcela = maxParcela > valorParcela ? valorParcela : maxParcela;
	}

	public String vender() {

		((HttpSession) FacesContext.getCurrentInstance().getExternalContext()
				.getSession(true)).setAttribute("carrinho", carrinho);

		((HttpSession) FacesContext.getCurrentInstance().getExternalContext()
				.getSession(true)).setAttribute("tipoFrete", tipoFrete == null ? TipoFrete.PAC : tipoFrete);

		
		HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
				.getExternalContext().getSession(true);
		Usuario usuario = (Usuario) session.getAttribute(Usuario.class
				.toString());

		if (usuario == null) {
			FacesContext.getCurrentInstance().getExternalContext().getFlash()
					.put("proximaPagina", "/vender/finalizarcompra");
			return "/autenticar/autenticar.jsf?faces-redirect=true";
		}

		return "finalizarcompra.jsf?faces-redirect=true";
	}

	private void addMessage(String message, FacesMessage.Severity severity) {

		FacesContext.getCurrentInstance().addMessage(null,
				new FacesMessage(severity, message, ""));

	}
	
	public List<TipoFrete> getListTipoFrete(){
		
		List<TipoFrete> listTipoFrete = new ArrayList<TipoFrete>();
		for( TipoFrete tf :  TipoFrete.values() )
			listTipoFrete.add(tf);
		
		return listTipoFrete;
			
	}

	/*
	 * GETTER AND SETTER
	 */

	public Produto getProduto() {
		return produto;
	}

	public void setProduto(Produto produto) {
		this.produto = produto;
	}

	public Venda getCarrinho() {
		return carrinho;
	}

	public void setCarrinho(Venda carrinho) {
		this.carrinho = carrinho;
	}

	public int getMaxParcela() {
		return maxParcela;
	}

	public void setMaxParcela(int maxParcela) {
		this.maxParcela = maxParcela;
	}

	public Frete getFrete() {
		return frete;
	}

	public void setFrete(Frete frete) {
		this.frete = frete;
	}

	public String getCepDestino() {
		return cepDestino;
	}

	public void setCepDestino(String cepDestino) {
		this.cepDestino = cepDestino;
	}

	public TipoFrete getTipoFrete() {
		return tipoFrete;
	}

	public void setTipoFrete(TipoFrete tipoFrete) {
		this.tipoFrete = tipoFrete;
	}

	public Frete getFreteProduto() {
		return freteProduto;
	}

	public void setFreteProduto(Frete freteProduto) {
		this.freteProduto = freteProduto;
	}

}
